package org.darkforest.common.services.impl;

import org.darkforest.common.logger.Logger;
import org.darkforest.common.services.*;
import org.darkforest.common.util.DateUtil;
import org.darkforest.common.util.SerialNumGenerator;
import org.darkforest.dao.mapper.*;
import org.darkforest.enums.OrderStatusEnum;
import org.darkforest.enums.PdLogTypeEnum;
import org.darkforest.model.*;
import org.darkforest.ucenter.service.UserOrderService;
import org.darkforest.vo.MemberBase;
import org.darkforest.vo.PayInfoVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.ModelAndView;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by liu on 15/1/18.
 */
@Service("refundReturnService")
@Transactional
public class RefundReturnServiceImpl implements RefundReturnService {
    @Autowired
    private RefundReturnMapper refundReturnMapper;
    @Autowired
    private UserOrderService userOrderService;
    @Autowired
    protected MemberMapper memberMapper;
    @Autowired
    private PdLogMapper pdLogMapper;
    @Autowired
    private WxJSSdkService wxJSSdkService;
    @Autowired
    private OrderPayService orderPayService;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private GoodsMapper goodsMapper;
    @Autowired
    private MessageAndNoticeService messageAndNoticeService;
    @Autowired
    private OrderGoodsMapper orderGoodsMapper;
    @Autowired
    private OrderGiftCodeMapper orderGiftCodeMapper;
    @Autowired
    private OrderCommonMapper orderCommonMapper;

    @Override
    public void selectListByCondition(RefundReturnSearchBean page) {
        page.setResultList(refundReturnMapper.selectListByCondition(page));
    }

    @Override
    public RefundReturn getRefundReturnById(int id) {
        return refundReturnMapper.selectByPrimaryKey(id);
    }

    @Override
    public int updateRefundReturn(RefundReturn refund) {
        return refundReturnMapper.updateRefund(refund);
    }

    @Override
    public int updateRebackReturn(RefundReturn refund) {
        return refundReturnMapper.updateReback(refund);
    }

    /**
     * 微信提交退款申请
     *
     * @param reason
     * @param memberId
     * @param orderId  @return
     * @param goodsId
     * @param reasonId
     */
    @Override
    public int addWxRefundReturn(String reason, Integer memberId, Integer orderId, String[] goodsId, Integer reasonId) {

        OrderVo order = userOrderService.getOrderDetailById(memberId, orderId);
        int i = 0;
        for (String str : goodsId) {
            for (OrderGoods orderGoods : order.getGoods()) {
                Integer gsid = Integer.parseInt(str);//订单中商品ID
                if (gsid == orderGoods.getGoodsId()) {

                    RefundReturn refundReturn = new RefundReturn();
                    refundReturn.init();
                    refundReturn.setAddTime(DateUtil.unixTimeStampInt().intValue());
                    refundReturn.setStoreName(order.getStoreName());
                    refundReturn.setStoreId(order.getStoreId());
                    refundReturn.setBuyerId(order.getBuyerId());
                    refundReturn.setBuyerName(order.getBuyerName());
                    refundReturn.setGoodsId(gsid);
                    refundReturn.setBuyerMessage(reason);
                    refundReturn.setGoodsImage(orderGoods.getGoodsImage());
                    refundReturn.setGoodsName(orderGoods.getGoodsName());
                    refundReturn.setGoodsNum(orderGoods.getGoodsNum());
                    refundReturn.setGoodsState(Integer.parseInt(order.getOrderState()));
                    refundReturn.setReasonId(reasonId);
                    refundReturn.setReasonInfo(reason);
                    refundReturn.setRefundAmount(orderGoods.getGoodsPayPrice());
                    refundReturn.setRefundState(1);
                    refundReturn.setOrderId(orderId);
                    refundReturn.setOrderSn(order.getOrderId() + "");
                    refundReturn.setRefundSn(order.getPaySn());
                    refundReturn.setRefundType(1);
                    refundReturn.setSellerState(1);
                    refundReturn.setReturnChannel(order.getPaymentCode());
                    refundReturn.setOrderAmount(order.getOrderAmount());

                    i += refundReturnMapper.insertSelective(refundReturn);
                }
            }

        }
        return i;
    }

    @Override
    public int updateRefundByOderSn(RefundReturn refund) {
        return refundReturnMapper.updateRefundByOderSn(refund);
    }

    @Override
    public Map<String, Object> refundMoneyAndGoodsStatistics(int flag, Integer storeId) {
        List<Map<String, Object>> list;
        Map map = new HashMap();
        map.put("flag", flag);
        map.put("storeId", storeId);
        list = refundReturnMapper.refundMoneyAndGoodsStatistics(map);

        return getRegionHashMap(list);
    }


    /**
     * 将一些特殊的List<Map<String,Object>> 转化成Map<String,Object>
     *
     * @param regionMap
     * @return
     */
    public static Map<String, Object> getRegionHashMap(List<Map<String, Object>> regionMap) {

        Map<String, Object> resultMap = new HashMap<String, Object>();
        for (Map<String, Object> map : regionMap) {
            String code = null;
            Object value = null;
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                if ("code_field".equals(entry.getKey())) {
                    code = entry.getValue() + "";
                } else if ("value_field".equals(entry.getKey())) {
                    value = entry.getValue();
                }
            }
            resultMap.put(code, value);
        }
        return resultMap;
    }

    @Override
    @Transactional
    public int refundForPdAmount(RefundReturn refund, BigDecimal refundAmount, Member leader, Member buyer) {
        int i = 0;

//      更新余额
        buyer.setAvailablePredeposit(buyer.getAvailablePredeposit().add(refundAmount));
        i = memberMapper.updateMemberBaseInfo(buyer);
//      记录日志
        PdLog buyerPdLog = new PdLog();
        buyerPdLog.setLgMemberId(buyer.getMemberId());
        buyerPdLog.setLgMemberName(buyer.getMemberName());
        buyerPdLog.setLgAddTime(DateUtil.unixTimeStampInt().intValue());
        buyerPdLog.setLgType("refund");
        buyerPdLog.setLgFreezeAmount(BigDecimal.ZERO);
        buyerPdLog.setLgAvAmount(refundAmount);
        buyerPdLog.setLgDesc(refund.getOrderSn() + "退款账到" + refundAmount + "元");
        buyerPdLog.setLgBalance(buyer.getAvailablePredeposit());
        buyerPdLog.setLgOrderId(refund.getOrderId());
        pdLogMapper.insert(buyerPdLog);
        messageAndNoticeService.sendPredepositChangeToUser(buyerPdLog);
        return i;
    }


    @Override
    @Transactional
    public String refundDo(RefundReturn refund) {
        Map<String, Object> mapParam = new HashMap<String, Object>();
        Member leader = memberMapper.getMemberById(1);
        Member buyer = memberMapper.getMemberById(refund.getBuyerId());
        Order order = orderMapper.selectByPrimaryKey(refund.getOrderId());
        String pay_type = order.getPaymentCode();
        //领取退款
        if (pay_type.equals("3")) {
            OrderCommon orderCommon = orderCommonMapper.selectByPrimaryKey(order.getOrderId());
            OrderGiftCode orderGiftCode = orderGiftCodeMapper.selectByGiftCode(orderCommon.getGiftCode());
            Order sendOrder = orderMapper.selectByPrimaryKey(Integer.parseInt(orderGiftCode.getGenerateOrderId()));
            if ("1".equals(sendOrder.getPaymentCode())) { //微信退款
                boolean res = wxJSSdkService.wxRefund(refund, sendOrder);
            } else if ("2".equals(sendOrder.getPaymentCode())) { //余额退款
                buyer = memberMapper.getMemberById(sendOrder.getBuyerId());
                OrderPay orderPay = new OrderPay();
                orderPay.setOrderSn(sendOrder.getOrderSn().toString());
                List<OrderPay> orderPayList = orderPayService.findOrderPayInfoByCondition(orderPay);
                if (orderPayList.size() > 0 && orderPayList != null) {
                    this.refundForPdAmount(refund, refund.getRefundAmount(), leader, buyer);
                }
                refund.setAdminMessage("完成退款！");
                refund.setAdminTime(DateUtil.unixTimeStampInt().intValue());
                refund.setRefundState(3);
                this.updateRefundReturn(refund);//修改微信退款状态
                order.setOrderState("0");
                order.setLockState(0);
                if (refund.getOrderAmount().compareTo(refund.getRefundAmount()) == 1) {
                    order.setRefundState(2);
                } else {
                    order.setRefundState(1);
                }
                orderMapper.updateByPrimaryKey(order);
            }
            //注销礼品码
            orderGiftCode.setCodeState(3);
            orderGiftCodeMapper.updateByPrimaryKeySelective(orderGiftCode);
            //其他正常退款
        } else {
            if ("1".equals(refund.getReturnChannel())) { //微信退款
                boolean res = wxJSSdkService.wxRefund(refund, order);
            } else if ("2".equals(refund.getReturnChannel())) { //余额退款
                OrderPay orderPay = new OrderPay();
                orderPay.setOrderSn(refund.getOrderSn());
                List<OrderPay> orderPayList = orderPayService.findOrderPayInfoByCondition(orderPay);
                if (orderPayList.size() > 0 && orderPayList != null) {
                    this.refundForPdAmount(refund, refund.getRefundAmount(), leader, buyer);
                }
                refund.setAdminMessage("完成退款！");
                refund.setAdminTime(DateUtil.unixTimeStampInt().intValue());
                refund.setRefundState(3);
                this.updateRefundReturn(refund);//修改微信退款状态
                order.setOrderState("0");
                order.setLockState(0);
                if (refund.getOrderAmount().compareTo(refund.getRefundAmount()) == 1) {
                    order.setRefundState(2);
                } else {
                    order.setRefundState(1);
                }
                orderMapper.updateByPrimaryKey(order);
            }
        }
        return "";
    }

    @Override
    public void refundReturnSuccessUpdate(OrderPay pay) {
        RefundReturn refund = new RefundReturn();
        refund.setOrderSn(pay.getOrderSn());
        refund.setRefundState(3);
        refund.setAdminMessage("完成退款！");
        refund.setAdminTime(DateUtil.unixTimeStampInt().intValue());
        refundReturnMapper.updateRefundByOderSn(refund);
        refund = refundReturnMapper.selectListByOrderSn(pay.getOrderSn());
        OrderGoods goods = new OrderGoods();
        goods.setGoodsId(refund.getGoodsId());
        goodsMapper.updateGoodsStorageDirect(goods);
    }

    @Override
    public List<Map<String, Object>> findRefundStatisticsByCondition(RefundReturnSearchBean page) {
        return refundReturnMapper.findRefundStatisticsByCondition(page);
    }


    @Override
    @Transactional
    public PdLog cancelOrder(OrderVo vo) {
        Map<String, Integer> param = new HashMap<String, Integer>();
        param.put("id", vo.getOrderId());
        param.put("buyerId", vo.getBuyerId());
        OrderVo getOrder = orderMapper.selectById(param);
        PdLog pdLog = new PdLog();
        if (getOrder != null && getOrder.getOrderState().equals("20")) {
            vo.setFinnshedTime(DateUtil.unixTimeStampInt().intValue());
            vo.setOrderState(OrderStatusEnum.CANCEL.getValue() + "");
            orderMapper.updateByPrimaryKeySelective(vo);
            String pay_type = getOrder.getPaymentCode();
            //微信退款
            if (pay_type.equals("1")) {
                RefundReturn refundReturn = new RefundReturn();
                refundReturn.init();
                refundReturn.setGoodsName(getOrder.getGoods().get(0).getGoodsName());
                refundReturn.setAddTime(DateUtil.unixTimeStampInt().intValue());
                refundReturn.setStoreName(getOrder.getStoreName());
                refundReturn.setStoreId(getOrder.getStoreId());
                refundReturn.setBuyerId(getOrder.getBuyerId());
                refundReturn.setBuyerName(getOrder.getBuyerName());
                refundReturn.setGoodsId(0);
                refundReturn.setOrderGoodsId(0);
                refundReturn.setReasonId(0);
                refundReturn.setGoodsImage(getOrder.getGoods().get(0).getGoodsImage());
                refundReturn.setReasonInfo("全额退款");
                refundReturn.setRefundAmount(getOrder.getOrderAmount());
                refundReturn.setRefundState(3);
                refundReturn.setOrderId(getOrder.getOrderId());
                refundReturn.setOrderSn(getOrder.getOrderSn() + "");
//                refundReturn.setRefundSn(SerialNumGenerator.getOrderSn(SerialNumGenerator.ORDERCH_PC).toString());
                refundReturn.setRefundType(1);
                refundReturn.setSellerState(2);
                refundReturn.setReturnChannel(getOrder.getPaymentCode());
                refundReturn.setOrderAmount(getOrder.getOrderAmount());
                refundReturnMapper.insertSelective(refundReturn);
                wxJSSdkService.wxRefund(refundReturn, getOrder);
                //余额退款
            } else if (pay_type.equals("2")) {
                Member mb = memberMapper.getMemberById(getOrder.getBuyerId());
                mb.setAvailablePredeposit(mb.getAvailablePredeposit().add(getOrder.getOrderAmount()));
                memberMapper.updateMemberBaseInfo(mb);
                pdLog.setLgMemberId(mb.getMemberId());
                pdLog.setLgMemberName(mb.getMemberName());
                pdLog.setLgAvAmount(getOrder.getOrderAmount());
                pdLog.setLgAddTime(Integer.parseInt(DateUtil.unixTimeStamp()));
                pdLog.setLgDesc(PdLogTypeEnum.ORDER_CANCEL.getText() + getOrder.getOrderSn());
                pdLog.setLgType("order_cancel");
                pdLogMapper.insertSelective(pdLog);
                //礼品吗领取
            } else if (pay_type.equals("3")) {
                OrderGiftCode orderGiftCode = orderGiftCodeMapper.selectByGiftCode(getOrder.getCommon().getGiftCode());
                Order or = orderMapper.selectByPrimaryKey(Integer.parseInt(orderGiftCode.getGenerateOrderId()));
                Map<String, Integer> pm = new HashMap<String, Integer>();
                pm.put("id", Integer.parseInt(orderGiftCode.getGenerateOrderId()));
                pm.put("buyerId", or.getBuyerId());
                OrderVo senderOrder = orderMapper.selectById(pm);
                String paytype = senderOrder.getPaymentCode();
                if (paytype.equals("1")) {
                    RefundReturn refundReturn = new RefundReturn();
                    refundReturn.init();
                    refundReturn.setGoodsName(senderOrder.getGoods().get(0).getGoodsName());
                    refundReturn.setAddTime(DateUtil.unixTimeStampInt().intValue());
                    refundReturn.setStoreName(senderOrder.getStoreName());
                    refundReturn.setStoreId(senderOrder.getStoreId());
                    refundReturn.setBuyerId(senderOrder.getBuyerId());
                    refundReturn.setBuyerName(senderOrder.getBuyerName());
                    refundReturn.setGoodsId(0);
                    refundReturn.setOrderGoodsId(senderOrder.getGoods().get(0).getGoodsId());
                    refundReturn.setReasonId(0);
                    refundReturn.setReasonInfo("部分退款");
                    refundReturn.setRefundAmount(getOrder.getOrderAmount());
                    refundReturn.setRefundState(3);
                    refundReturn.setGoodsImage(getOrder.getGoods().get(0).getGoodsImage());
                    refundReturn.setOrderId(senderOrder.getOrderId());
                    refundReturn.setOrderSn(senderOrder.getOrderSn() + "");
//                    refundReturn.setRefundSn(SerialNumGenerator.getOrderSn(SerialNumGenerator.ORDERCH_PC).toString());
                    refundReturn.setRefundType(1);
                    refundReturn.setSellerState(2);
                    refundReturn.setReturnChannel(senderOrder.getPaymentCode());
                    refundReturn.setOrderAmount(senderOrder.getOrderAmount());
                    refundReturnMapper.insertSelective(refundReturn);
                    wxJSSdkService.wxRefund(refundReturn, senderOrder);
                } else if (paytype.equals("2")) {
                    Member mb = memberMapper.getMemberById(senderOrder.getBuyerId());
                    mb.setAvailablePredeposit(mb.getAvailablePredeposit().add(getOrder.getOrderAmount()));
                    memberMapper.updateMemberBaseInfo(mb);
                    pdLog.setLgMemberId(mb.getMemberId());
                    pdLog.setLgMemberName(mb.getMemberName());
                    pdLog.setLgAvAmount(getOrder.getOrderAmount());
                    pdLog.setLgAddTime(Integer.parseInt(DateUtil.unixTimeStamp()));
                    pdLog.setLgDesc(PdLogTypeEnum.ORDER_CANCEL.getText() + getOrder.getOrderSn());
                    pdLog.setLgType("order_cancel");
                    pdLogMapper.insertSelective(pdLog);
                }
                //注销礼品码
                orderGiftCode.setCodeState(3);
                orderGiftCodeMapper.updateByPrimaryKeySelective(orderGiftCode);
            }
            //获取订单商品列表 依次还原商品库存以及销量
            List<OrderGoods> goodsList = orderGoodsMapper.findOrderGoodsListByOrderId(getOrder.getOrderId());
            for (OrderGoods goods : goodsList) {
                goodsMapper.updateGoodsStorageDirect(goods);
            }
        } else if (getOrder != null && getOrder.getOrderState().equals("10")) {
            vo.setFinnshedTime(DateUtil.toUnixTimeStamp(DateUtil.toTimeString(new Date())));
            vo.setOrderState(OrderStatusEnum.CANCEL.getValue() + "");
            orderMapper.updateByPrimaryKeySelective(vo);
        }
        return pdLog;
    }

    /*****
     * 300 部分已使用
     * 301 超过了24小时
     * 302 取消成功
     *
     * @param vo
     * @return
     */
    @Override
    @Transactional
    public String cancelGiftCodeOrder(OrderVo vo) {
        Map<String, Integer> param = new HashMap<String, Integer>();
        param.put("id", vo.getOrderId());
        param.put("buyerId", vo.getBuyerId());
        OrderVo getOrder = orderMapper.selectById(param);
        OrderGiftCode record = new OrderGiftCode();
        record.setGenerateOrderId(getOrder.getOrderId() + "");
        record.setCodeState(1);
        List<OrderGiftCode> codes = orderGiftCodeMapper.selectByCondition(record);
        if (codes != null && getOrder.getCommon() != null && getOrder.getCommon().getCodeNum() != codes.size()) {
            return "300";
        }

        Integer nowTime = DateUtil.toUnixTimeStamp(DateUtil.toTimeString(new Date()));
        Integer addTime = getOrder.getAddTime();
        if (nowTime - addTime < 0 || nowTime - addTime > 86400) {
            return "301";
        }
        PdLog pdLog = new PdLog();
        if (getOrder != null && (getOrder.getOrderState().equals("30") || getOrder.getOrderState().equals("40")) && getOrder.getPaymentCode().equals("2")) {
            vo.setFinnshedTime(DateUtil.unixTimeStampInt().intValue());
            vo.setOrderState(OrderStatusEnum.CANCEL.getValue() + "");
            orderMapper.updateByPrimaryKeySelective(vo);
            String paytype = getOrder.getPaymentCode();
            if (paytype.equals("1")) {
                RefundReturn refundReturn = new RefundReturn();
                refundReturn.init();
                refundReturn.setAddTime(DateUtil.unixTimeStampInt().intValue());
                refundReturn.setGoodsName(getOrder.getGoods().get(0).getGoodsName());
                refundReturn.setStoreName(getOrder.getStoreName());
                refundReturn.setStoreId(getOrder.getStoreId());
                refundReturn.setBuyerId(getOrder.getBuyerId());
                refundReturn.setBuyerName(getOrder.getBuyerName());
                refundReturn.setGoodsId(0);
                refundReturn.setOrderGoodsId(0);
                refundReturn.setReasonId(0);
                refundReturn.setReasonInfo("全部");
                refundReturn.setRefundAmount(getOrder.getOrderAmount());
                refundReturn.setRefundState(3);
                refundReturn.setGoodsImage(getOrder.getGoods().get(0).getGoodsImage());
                refundReturn.setOrderId(getOrder.getOrderId());
                refundReturn.setOrderSn(getOrder.getOrderSn() + "");
                refundReturn.setRefundType(1);
                refundReturn.setSellerState(2);
                refundReturn.setReturnChannel(getOrder.getPaymentCode());
                refundReturn.setOrderAmount(getOrder.getOrderAmount());
                refundReturnMapper.insertSelective(refundReturn);
                wxJSSdkService.wxRefund(refundReturn, getOrder);
            } else if (paytype.equals("2")) {
                Member mb = memberMapper.getMemberById(getOrder.getBuyerId());
                mb.setAvailablePredeposit(mb.getAvailablePredeposit().add(getOrder.getOrderAmount()));
                memberMapper.updateMemberBaseInfo(mb);
                pdLog.setLgMemberId(mb.getMemberId());
                pdLog.setLgMemberName(mb.getMemberName());
                pdLog.setLgAvAmount(getOrder.getOrderAmount());
                pdLog.setLgAddTime(Integer.parseInt(DateUtil.unixTimeStamp()));
                pdLog.setLgDesc(PdLogTypeEnum.ORDER_CANCEL.getText() + getOrder.getOrderSn());
                pdLog.setLgType("order_cancel");
                pdLogMapper.insertSelective(pdLog);
            }
            //注销礼品码
            for(OrderGiftCode orderGiftCode:codes){
                orderGiftCode.setCodeState(3);
                orderGiftCodeMapper.updateByPrimaryKeySelective(orderGiftCode);
            }

            //获取订单商品列表 依次还原商品库存以及销量
            List<OrderGoods> goodsList = orderGoodsMapper.findOrderGoodsListByOrderId(getOrder.getOrderId());
            for (OrderGoods goods : goodsList) {
                goodsMapper.updateGoodsStorageDirect(goods);
            }
        }
        return "302";
    }
}
